﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kooboo.HtmlFunc.Models;

namespace Kooboo.HtmlFunc.Providers {

    public class Provider {
        private static IProviderFactory _factory;
        public static IProviderFactory Factory {
            get {
                if (_factory == null)
                    _factory = new DefaultProviderFactory();
                return _factory;
            }
            set {
                _factory = value;
            }
        }
    }

    public interface IProviderFactory {
        TProvider GetProvider<TProvider>();
        void RegisterProvider<TProvider>(Type provider);
    }

    public class DefaultProviderFactory : IProviderFactory {

        private IDictionary<Type, Type> _providers;
        public DefaultProviderFactory() {
            _providers = new Dictionary<Type, Type>();
            // register
            this.RegisterProvider<IAnalyseResult>(typeof(AnalyseResult));
            this.RegisterProvider<IAnchorTag>(typeof(AnchorTag));
            this.RegisterProvider<IBodyTag>(typeof(BodyTag));
            this.RegisterProvider<ICustom>(typeof(Custom));
            this.RegisterProvider<IDataItem>(typeof(DataItem));
            this.RegisterProvider<IDetail>(typeof(Detail));
            this.RegisterProvider<IHeadTag>(typeof(HeadTag));
            this.RegisterProvider<IHtmlBlockPart>(typeof(HtmlBlockPart));
            this.RegisterProvider<IHtmlPart>(typeof(HtmlPart));
            this.RegisterProvider<IHtmlTag>(typeof(HtmlTag));
            this.RegisterProvider<IImgTag>(typeof(ImgTag));
            this.RegisterProvider<IInnerPage>(typeof(InnerPage));
            this.RegisterProvider<ILabel>(typeof(Label));
            this.RegisterProvider<ILayout>(typeof(Layout));
            this.RegisterProvider<ILinkItem>(typeof(LinkItem));
            this.RegisterProvider<IList>(typeof(List));
            this.RegisterProvider<IMenu>(typeof(Menu));
            this.RegisterProvider<IMetaTag>(typeof(MetaTag));
            this.RegisterProvider<IPageSetting>(typeof(PageSetting));
            this.RegisterProvider<IPosition>(typeof(Position));
            this.RegisterProvider<IScriptTag>(typeof(ScriptTag));
            this.RegisterProvider<IStyleTag>(typeof(StyleTag));
            this.RegisterProvider<ITitleTag>(typeof(TitleTag));
            this.RegisterProvider<IViewPart>(typeof(ViewPart));
        }

        public TProvider GetProvider<TProvider>() {
            var typeKey = typeof(TProvider);
            if (_providers.ContainsKey(typeKey)) {
                return (TProvider)Activator.CreateInstance(_providers[typeKey]);
            } else {
                throw new KeyNotFoundException();
            }
        }

        public void RegisterProvider<TProvider>(Type providerType) {
            _providers[typeof(TProvider)] = providerType;
        }
    }
}
